﻿
// MFCApplication1Dlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "MFCApplication1.h"
#include "MFCApplication1Dlg.h"
#include "afxdialogex.h"
#include"locale.h"
#include <time.h>  
#include"shellapi.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CMFCApplication1Dlg 对话框



CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent)
	, m_range(1)
	, m_minusOrPlus(2)
	, m_papers(1)
	, m_several(51)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON2);
}

void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Radio(pDX, IDC_RADIO1, m_range);
	DDX_Radio(pDX, IDC_RADIO11, m_minusOrPlus);
	DDX_Text(pDX, IDC_EDIT1, m_papers);
	DDX_Text(pDX, IDC_EDIT2, m_several);
}

BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CMFCApplication1Dlg::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CMFCApplication1Dlg::OnBnClickedCancel)
	ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)
END_MESSAGE_MAP()


// CMFCApplication1Dlg 消息处理程序

BOOL CMFCApplication1Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标
	SetWindowText(_T("小学算术题生成工具 -- by Haroun "));
	
	setlocale(LC_CTYPE, "chs");
	// TODO: 在此添加额外的初始化代码

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CMFCApplication1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CMFCApplication1Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFCApplication1Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CMFCApplication1Dlg::OnBnClickedOk()
{
	GetDlgItem(IDOK)->EnableWindow(FALSE);
	GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
	// TODO: 在此添加控件通知处理程序代码
	CTime pctime;
	pctime = CTime::GetCurrentTime();             //获取当前时间日期  
	CString strDateTime = pctime.Format(_T("%Y-%m-%d_%H-%M-%S.docx"));   //格式化日期时间  

	if (OutResource(IDR_DOCX1, _T("docx"), strDateTime))
	{
		duckx::Document doc(strDateTime.GetString());
		doc.open();
		int i = 0;
		for (auto p = doc.paragraphs(); p.has_next(); p.next()) {
			for (auto r = p.runs(); r.has_next(); r.next()) {
				string tmp = r.get_text();
				if (tmp.size() > 0)
				{
					if (i == 0)
					{
						m_title = r.get_text();
					}
					if (i == 1)
					{
						m_name = r.get_text();
					}
					if (i == 2)
					{
						m_time = r.get_text();
					}
					if (i == 3)
					{
						m_error = r.get_text();
					}
					i++;
				}
			}
		}
	}
	else
	{
		GetDlgItem(IDOK)->EnableWindow(TRUE);
		GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
		return;
	}
	
	if (OutResource(IDR_DOCX2,_T("docx"), strDateTime))
	{
		string strTest = strDateTime.GetString();
		duckx::Document doc(strTest);
		doc.open();
		
		UpdateData(true);

		
		for (size_t ii = 0; ii < m_papers; ii++)
		{
			string title = "						";
			switch (m_range)
			{
			case 0:
				title.append("10");
				break;
			case 1:
				title.append("20");
				break;
			case 2:
				title.append("30");
				break;
			case 3:
				title.append("40");
				break;
			case 4:
				title.append("50");
				break;
			case 5:
				title.append("60");
				break;
			case 6:
				title.append("70");
				break;
			case 7:
				title.append("80");
				break;
			case 8:
				title.append("90");
				break;
			case 9:
				title.append("100");
				break;
			default:
				break;
			}

			doc.paragraphs().add(title.append(m_title), duckx::bold);
			doc.paragraphs().add("");
			string second = "	";
			second.append(m_name).append(":").append("				").append(m_time).append(":").append("				").append(m_error).append(":").append("				");
			doc.paragraphs().add(second, duckx::bold);
			doc.paragraphs().add("");

			std::vector<string> subjects = CreateRanges();
			auto randoms = CreateRandomNums(0, subjects.size()-1, m_several);
			if (randoms.size() == 0)
			{
				CString msg;
				msg.Format("您设置的每份计算题条数太多了，工具也无能为力了，请修改！");
				::AfxMessageBox(msg);
				GetDlgItem(IDOK)->EnableWindow(TRUE);
				GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
				return;
			}
			int three = 0;
			int several = m_several;
			string runbuf;
			for (std::vector<int>::iterator it = randoms.begin(); it != randoms.end(); it++)
			{
				runbuf.append(subjects.at(*it)).append("\t");
				three++;
				if (three >= 3 || several == 1)
				{
					doc.paragraphs().add(runbuf, duckx::bold);
					three = 0;
					runbuf = "";
				}
				several--;
			}
			doc.paragraphs().add("");
			doc.paragraphs().add("");
		}

		//duckx::Paragraph p = doc.paragraphs().insert_paragraph_after(title.append(m_title), duckx::bold);
		
		//p.add_run(m_name, duckx::none);
		//p.add_run(m_title, duckx::none);
		//p.add_run(m_time, duckx::none);
		//p.add_run(m_error, duckx::none);
		//p.add_run("italic, ", duckx::none);
		////p.add_run(top, duckx::none);
		//p.add_run("bold, ", duckx::bold);
		//p.add_run("underline, ", duckx::strikethrough);
		//p.add_run("superscript", duckx::superscript);
		//p.add_run(" or ");
		//p.add_run("subscript, ", duckx::subscript);
		//p.add_run("small caps, ", duckx::smallcaps);
		//p.add_run("and shadows, ", duckx::shadow);
		//p.add_run("and of course ");
		//p.add_run("combine them.", duckx::bold | duckx::italic | duckx::underline | duckx::smallcaps);

		doc.save();
		UpdateData(false);
	}
	else
	{
		GetDlgItem(IDOK)->EnableWindow(TRUE);
		GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
		return;
	}
	m_openfile = strDateTime;
	GetDlgItem(IDC_BUTTON1)->EnableWindow(TRUE);
	GetDlgItem(IDOK)->EnableWindow(TRUE);
	return;
	//CDialogEx::OnOK();
}



std::vector<int> CMFCApplication1Dlg::CreateRandomNums(int min, int max, int num)
{
	std::vector<int> res;
	res.clear();
	if (max - min + 1 < num)
	{
		return res;
	}
	srand(time(0));
	Sleep(1010);
	for (auto i{ 0 }; i < num; i++)
	{
		while (true)
		{
			auto temp{ rand() % (max + 1 - min) + min };
			auto iter{ find(res.begin(),res.end(),temp) };
			if (res.end() == iter)
			{
				res.push_back(temp);
				break;
			}
		}
	}
	return res;
}

std::vector<string> CMFCApplication1Dlg::CreateRanges()
{
	UpdateData(true);
	std::vector<string> res;
	for (int i = (m_range+1)*10;i > 0; i--)
	{
		for (size_t j = 1; j < i; j++)
		{
			string tmpm;
			int reslut = i - j;

			CString big,min,diff;
			big.Format("%d", i);
			min.Format("%d", j);
			diff.Format("%d", reslut);
			
			tmpm.append(big).append("\t-\t").append(min).append("\t=\t");
			string tmpp;
			tmpp.append(min).append("\t+\t").append(diff).append("\t=\t");
			if (m_minusOrPlus == 0)
			{
				res.push_back(tmpp);
			}
			else if (m_minusOrPlus == 1)
			{
				res.push_back(tmpm);
			}
			else
			{
				res.push_back(tmpp);
				res.push_back(tmpm);
			}
		}
	}
	UpdateData(false);
	return res;
}

bool CMFCApplication1Dlg::OutResource(UINT uID, CString csType, CString csOutputPath)
{
	CFile file;
	HMODULE hModule = GetModuleHandle(NULL);
	HRSRC hRes = FindResource(hModule, MAKEINTRESOURCE(uID), csType);
	if (hRes == NULL)
	{
		FreeResource(hRes);
	}
	else
	{
		HGLOBAL hglobal = LoadResource(hModule, hRes);
		if (hglobal == NULL)
		{
			FreeResource(hglobal);
			return false;
		}
		else
		{
			//释放文件
			/*
			HANDLE hCreateFile = CreateFile(csOutputPath, GENERIC_READ | GENERIC_WRITE,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
			if (hCreateFile == INVALID_HANDLE_VALUE)
			{
				CString str;
				str.Format(L"生成失败 %d", GetLastError());
				::AfxMessageBox(str);
				return false;
			}
			else
			{
				
			}*/

			LPBYTE lpByte = (LPBYTE)LockResource(hglobal);
			DWORD dwRcSize = SizeofResource(hModule, hRes);
			file.Open(csOutputPath, CFile::modeCreate | CFile::modeWrite);
			file.Write(lpByte, dwRcSize);
			file.Close();
		}
	}
	return true;
}


void CMFCApplication1Dlg::OnBnClickedCancel()
{
	// TODO: 在此添加控件通知处理程序代码
	CDialogEx::OnCancel();

	//duckx::Document doc("2020-02-29_13-07-45.docx");
	//doc.open();

	//duckx::Paragraph p = doc.paragraphs().insert_paragraph_after("You can insert text in ");
	//p.add_run("italic, ", duckx::none);
	//p.add_run("bold, ", duckx::bold);
	//p.add_run("underline, ", duckx::strikethrough);
	//p.add_run("superscript", duckx::superscript);
	//p.add_run(" or ");
	//p.add_run("subscript, ", duckx::subscript);
	//p.add_run("small caps, ", duckx::smallcaps);
	//p.add_run("and shadows, ", duckx::shadow);
	//p.add_run("and of course ");
	//p.add_run("combine them.", duckx::bold | duckx::italic | duckx::underline | duckx::smallcaps);

	//doc.save();


}


void CMFCApplication1Dlg::OnBnClickedButton1()
{
	/*UpdateData(true);
	CString out;
	out.Format(_T("%d  %d"), m_range,m_minusOrPlus);
	::AfxMessageBox(out);
	UpdateData(false);*/
	/*duckx::Document doc("tmp.docx");
	doc.open();
	for (auto p = doc.paragraphs(); p.has_next(); p.next()) {
		for (auto r = p.runs(); r.has_next(); r.next()) {
			cout << r.get_text() << endl;
			CString str;
			str.Format(_T("生成失败 %s"), r.get_text().c_str());
			::AfxMessageBox(str);
		}
	}*/
	if (m_openfile.GetLength() > 0)
	{
		ShellExecute(NULL, "open", m_openfile, NULL, NULL, SW_SHOWNORMAL);
	}
	
	// TODO: 在此添加控件通知处理程序代码
}
